import logging
from PyQt5 import QtWidgets, QtGui

# https://stackoverflow.com/a/51641943
# Uncomment below for terminal log messages
# logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(name)s - %(levelname)s - %(message)s')
"""
# https://stackoverflow.com/a/51641943

import sys
from PyQt5 import QtWidgets
import logging

# Uncomment below for terminal log messages
# logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(name)s - %(levelname)s - %(message)s')

class QTextEditLogger(logging.Handler):
    def __init__(self, parent):
        super().__init__()
        self.widget = QtWidgets.QPlainTextEdit(parent)
        self.widget.setReadOnly(True)

    def emit(self, record):
        msg = self.format(record)
        self.widget.appendPlainText(msg)


class MyDialog(QtWidgets.QDialog, QtWidgets.QPlainTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)

        logTextBox = QTextEditLogger(self)
        # You can format what is printed to text box
        logTextBox.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
        logging.getLogger().addHandler(logTextBox)
        # You can control the logging level
        logging.getLogger().setLevel(logging.DEBUG)

        self._button = QtWidgets.QPushButton(self)
        self._button.setText('Test Me')

        layout = QtWidgets.QVBoxLayout()
        # Add the new logging box widget to the layout
        layout.addWidget(logTextBox.widget)
        layout.addWidget(self._button)
        self.setLayout(layout)

        # Connect signal to slot
        self._button.clicked.connect(self.test)

    def test(self):
        logging.debug('damn, a bug')
        logging.info('something to remember')
        logging.warning('that\'s not right')
        logging.error('foobar')

app = QtWidgets.QApplication(sys.argv)
dlg = MyDialog()
dlg.show()
dlg.raise_()
sys.exit(app.exec_())
"""


class Highlighter(QtGui.QSyntaxHighlighter):
    def __init__(self, parent):
        super(Highlighter, self).__init__(parent)
        self.debugFormat = QtGui.QTextCharFormat()
        self.debugFormat.setForeground(QtGui.QColor("#0057e7"))
        self.infoFormat = QtGui.QTextCharFormat()
        self.infoFormat.setForeground(QtGui.QColor("#008744"))
        self.warningFormat = QtGui.QTextCharFormat()
        self.warningFormat.setForeground(QtGui.QColor("#ffa700"))
        self.errorFormat = QtGui.QTextCharFormat()
        self.errorFormat.setForeground(QtGui.QColor("#d62d20"))

    def highlightBlock(self, text):
        if " ERROR " in text:
            self.setFormat(0, len(text), self.errorFormat)
        elif " WARNING " in text or "WRITE" in text:
            self.setFormat(0, len(text), self.warningFormat)
        elif " INFO " in text:
            self.setFormat(0, len(text), self.infoFormat)
        elif " DEBUG " in text:
            self.setFormat(0, len(text), self.debugFormat)


class QTextEditLogger(logging.Handler):
    def __init__(self, parent, maxBlockCount=500):
        super().__init__()
        self.widget = QtWidgets.QPlainTextEdit(parent)
        self.widget.setAutoFillBackground(True)
        self.widget.setStyleSheet("background-color:#e5e6eb;")
        self.highlighter = Highlighter(self.widget.document())
        self.widget.setReadOnly(True)
        self.widget.setMaximumBlockCount(maxBlockCount)

    def emit(self, record):
        msg = self.format(record)
        self.widget.appendPlainText(msg)


class MyDialog(QtWidgets.QDialog, QtWidgets.QPlainTextEdit):
    def __init__(self, parent=None, logger=logging.getLogger(), maxBlockCount=500):
        super().__init__(parent)

        logTextBox = QTextEditLogger(parent=self, maxBlockCount=maxBlockCount)
        # You can format what is printed to text box
        logTextBox.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
        logger.addHandler(logTextBox)
        # logging.getLogger().addHandler(logTextBox)
        # You can control the logging level
        # logging.getLogger().setLevel(logging.DEBUG)
        layout = QtWidgets.QVBoxLayout()
        # Add the new logging box widget to the layout
        layout.addWidget(logTextBox.widget)
        self.setLayout(layout)
